package com.xinqi.modules.prepare.prepare.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinqi.common.core.utils.MessageUtils;
import com.xinqi.common.security.utils.UserHelp;
import com.xinqi.common.base.enums.YesNoEnum;
import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.base.response.Param;
import com.xinqi.common.mybatis.utils.Pages;
import com.xinqi.common.mybatis.utils.Queries;
import com.xinqi.modules.prepare.common.constant.PrepareConstant;
import com.xinqi.modules.prepare.common.enums.PrepareLimitEnum;
import com.xinqi.modules.prepare.prepare.convert.PrepareConvert;
import com.xinqi.modules.prepare.prepare.domain.PrepareEntity;
import com.xinqi.modules.prepare.prepare.dto.req.PrepareCreateDTO;
import com.xinqi.modules.prepare.prepare.dto.req.PrepareDeleteDTO;
import com.xinqi.modules.prepare.prepare.dto.req.PrepareQueryDTO;
import com.xinqi.modules.prepare.prepare.dto.req.PrepareUpdateDTO;
import com.xinqi.modules.prepare.prepare.dto.rsp.PrepareResultDTO;
import com.xinqi.modules.prepare.prepare.manager.PrepareManager;
import com.xinqi.modules.prepare.prepare.manager.PrepareMemberManager;
import com.xinqi.modules.prepare.prepare.service.PrepareService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.xinqi.common.base.error.CommonErrors.BAD_REQUEST;

/**
 * 备课区服务层实现
 *
 * @author: system
 * @date: 2023/03/19
 */
@Validated
@Service("prepareService")
@RequiredArgsConstructor
public class PrepareServiceImpl implements PrepareService {
    private final PrepareConvert prepareConvert;
    private final PrepareManager prepareManager;
    private final PrepareMemberManager prepareMemberManager;

    /**
     * 分页查询 备课区数据
     */
    @Override
    @DS("slaver")
    public PageInfo<PrepareResultDTO> page(Param pageable, PrepareQueryDTO query) {
        Page<PrepareResultDTO> page = prepareManager.findPage(
            Pages.page(pageable, OrderItem.desc("a.id")),
            query);
        return Pages.convert(page);
    }

    /**
     * 获取当前用户备课区
     */
    @Override
    public List<PrepareResultDTO> getCurrentUserPrepare() {
        Long userId = UserHelp.userId();
        PrepareQueryDTO dto = new PrepareQueryDTO();
        dto.setUserId(userId);
        dto.setIsSynergy(YesNoEnum.YES.ordinal());
        List<PrepareResultDTO> list = find(dto);

        // 备课区为空 或 自己创建的备课区为空
        if (CollectionUtils.isEmpty(list)
            || CollectionUtils.isEmpty(list.stream().filter(v -> Objects.equals(userId, v.getUserId())).collect(Collectors.toList()))) {
            // 查询不到-备课区-初始化默认备课区
            this.insertDefault(userId);
            // 重新获取备课区列表
            list = find(dto);
        }

        list.forEach(v -> {
            if (v.getIsSynergy() == null) {
                v.setIsSynergy(YesNoEnum.NO.ordinal());
            }
        });
        return list;
    }

    /**
     * 查询 备课区数据
     */
    @Override
    public List<PrepareResultDTO> find(PrepareQueryDTO query) {
        return prepareManager.findList(query);
    }

    private LambdaQueryWrapper<PrepareEntity> wrapper(PrepareQueryDTO query) {
        LambdaQueryWrapper<PrepareEntity> wrapper = Queries.lambda();
        Queries.accept(query.getId(), v -> wrapper.eq(PrepareEntity::getId, v));
        Queries.accept(query.getUserId(), v -> wrapper.eq(PrepareEntity::getUserId, v));
        Queries.accept(query.getName(), v -> wrapper.like(PrepareEntity::getName, v));
        return wrapper;
    }

    /**
     * 根据id查询 备课区数据
     */
    @Override
    public PrepareResultDTO findById(Long id) {
        BAD_REQUEST.check(Objects.nonNull(id), "ID不能为空");
        return Optional.ofNullable(prepareManager.findById(id)).map(prepareConvert::convert).orElse(null);
    }

    /**
     * 新增 备课区
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insert(@Valid PrepareCreateDTO dto) {
        Long userId = UserHelp.userId();
        dto.setUserId(userId);
        Long count = prepareManager.prepareCount(userId, false);
        PrepareLimitEnum.备课区创建上限.check(count + 1);
        BAD_REQUEST.check(!Objects.equals(dto.getName(), PrepareConstant.PREPARE_DEFAULT_NAME), "备课区名称不能为默认备课区");
        check(userId, dto.getName(), null);
        PrepareEntity entity = prepareConvert.create(dto);
        entity.setIsDefault(YesNoEnum.NO.ordinal());
        entity.setIsEdit(YesNoEnum.YES.ordinal());
        // 保存备课区
        prepareManager.save(entity);
        // 添加组长
        prepareMemberManager.addLeader(entity);
        return entity.getId();
    }

    /**
     * 新增 默认备课区
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long insertDefault(Long userId) {
        // 保存备课区
        Long prepareId = prepareManager.insertDefault(userId);
        // 添加组长
        prepareMemberManager.addLeader(prepareId, userId);
        return prepareId;
    }

    private void check(Long userId, String name, Long oldId) {
        BAD_REQUEST.check(!isExistName(userId, name, oldId), "备课区名称已存在");
    }

    /**
     * 新增 备课区数据
     */
    @Override
    public boolean isExistName(Long userId, String name, Long oldId) {
        BAD_REQUEST.check(userId != null, "用户不能为空");
        BAD_REQUEST.check(name != null, "备课区名称不能为空");
        return prepareManager.isExistName(userId, name, oldId);
    }

    /**
     * 根据id修改 备课区数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateById(@Valid PrepareUpdateDTO dto) {
        Long userId = UserHelp.userId();
        PrepareEntity old = Optional.ofNullable(prepareManager.getById(dto.getId())).orElseThrow(() -> BAD_REQUEST.asException(MessageUtils.message("remind.content.prepare.not.blank")));
//        BAD_REQUEST.check(!Objects.equals(old.getIsDefault(), YesNoEnum.YES.ordinal()), "默认备课区不能修改");
        check(userId, dto.getName(), old.getId());
        PrepareEntity entity = prepareConvert.update(dto);
        return prepareManager.updateById(entity);
    }

    /**
     * 根据id删除 备课区数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteById(Long id) {
        Long userId = UserHelp.userId();
        BAD_REQUEST.check(Objects.nonNull(id), "ID不能为空");
        PrepareEntity entity = Optional.ofNullable(prepareManager.getById(id)).orElseThrow(() -> BAD_REQUEST.asException(MessageUtils.message("remind.content.prepare.not.blank")));
        BAD_REQUEST.check(Objects.equals(userId, entity.getUserId()), "只能删除自己创建的备课区");
        Long prepareCount = prepareManager.prepareCount(userId);
        if (prepareCount < 2) {
            throw BAD_REQUEST.asException("备课区最少有一个");
        }
//        BAD_REQUEST.check(!Objects.equals(entity.getIsDefault(), YesNoEnum.YES.ordinal()), "默认备课区不能删除");
        return prepareManager.removeById(id);
    }

    /**
     * 根据id删除 备课区数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteById(PrepareDeleteDTO dto) {
        return deleteById(dto.getId());
    }

}
